#ifndef FUSEVM_TYPES_H
#define FUSEVM_TYPES_H

#include <unistd.h>

#include <cstring>
#include <cstdlib>
#include <list>
#include <map>

#define BLOCKSIZE 2 * 1024 *1024
//#define BLOCKSIZE 4 * 1024
#define MAX_INODE (1024UL * 1024 * 1024 * 16)
#define MAX_BLOCKS (1024UL * 1024 * 1024 * 16)
#define MAX_NAME 255
#define FS_ID 0x0123456701234567

class FileNode;
class FuseVMData;

struct DataSegment {
    off_t start;
    off_t end;
};

enum FILE_TYPE
{
    TYPE_NONE = 0,
    TYPE_FILE = 1,
    TYPE_VSPHERE = 2,
    TYPE_FSPHERE = 3
};

/**
 * Parameters for command-line argument processing function
 */
struct vmfuse_param
{
    // help shown
    bool help;
    // version information shown
    bool version;
    //choose store new disk file data in memory or not
    bool memoryFlag;
    //tmp directory to store new disk file data
    char storeDir[512];
    // number of string arguments
    int strArgCount;
    // a exist file name
    char fileName[512];
    // backup filelist
    char backupFilelist[10240];
    // backup disklist
    char backupDisklist[1024];
    //vm type
    int type;
};

struct ltstr
{

    bool operator()(const char *s1, const char *s2) const
    {
        const char *e1, *e2;
        char cmp1, cmp2;
        // set e1 and e2 to the last character in the string that is not a slash
        for (e1 = s1 + strlen(s1) - 1; e1 > s1 && *e1 == '/'; --e1)
            ;
        for (e2 = s2 + strlen(s2) - 1; e2 > s2 && *e2 == '/'; --e2)
            ;
        // compare strings until e1 and e2
        for (; s1 <= e1 && s2 <= e2 && *s1 == *s2; s1++, s2++)
            ;
        cmp1 = (s1 <= e1) ? *s1 : '\0';
        cmp2 = (s2 <= e2) ? *s2 : '\0';
        return cmp1 < cmp2;
    }
};

typedef std::list<FileNode *> nodelist_t;
typedef std::map<const char *, FileNode *, ltstr> filemap_t;

#endif
